package edu.wpi.cs509.ui;

import java.util.List;

import javax.swing.JFrame;

import edu.wpi.cs509.clientlogic.UserSession;
import edu.wpi.cs509.representation.GameListItem;
import edu.wpi.cs509.ui.intfc.ClientLogicNotify;
import edu.wpi.cs509.ui.intfc.GameInterface;
import edu.wpi.cs509.ui.intfc.PlayerStatsInterface;
import edu.wpi.cs509.ui.intfc.RulesInterface;

/**
 * The SessionEventHandler class implements the event handler for processing
 * asynchronous events from the client logic.
 *  
 * @author afoltan
 *
 */
public class ClientLogicNotifyHandler implements ClientLogicNotify {

	// The instance of the stratego client
	private A__MainStrategoClient client;
	
	/**
	 * Constructor for the session event handler
	 * @param client - the stratego client instance
	 */
	public ClientLogicNotifyHandler( A__MainStrategoClient client ) {
		this.client = client;
	}

	/**
	 * Trace support
	 */
	private void trace(String func) {
		System.out.println("UI <----- "+func+" ----- ClientLogic");
	}

	@Override
	public void ServerConnectionLost() {
		trace("ServerConnectionLost()");
		
		Dialog.displayConnectionLostDialog();

		client.setState( ClientState.LOGGED_OUT );
		client.displayMainFrame();
	}

	@Override
	public void notifyLoginSuccess(UserSession session) {
		trace("notifyLoginSuccess()");

		if (session == null) {
			System.out.println("ERROR::  notifyLoginSuccess(UserSession session) passed null session !!");
			return;
		}

		client.setUserSession(session);
		client.getClientFrame().displayGameListPanel();
		client.setState( ClientState.LOGGED_IN );
		client.displayMainFrame();
	}

	@Override
	public void notifyLeaderBoard(List<PlayerStatsInterface> statsList, int rank, int totalPlayers) {
		trace("notifyLeaderBoard()");

		if (statsList == null) {
			System.out.println("ERROR::  notifyLeaderBoard(List<PlayerStatsInterface> statsList, int rank, int totalPlayers) passed null statsList !!");
			return;
		}
		
		if (client.isLoggedIn()) {
			client.displayLeaderBoard( statsList, rank );
		} else {
			System.out.println("notifyLeaderBoard() received while player is logged out");
		}
	}

	@Override
	public void notifyPlayerStats(PlayerStatsInterface myStats) {
		trace("notifyPlayerStats()");

		if (myStats == null) {
			System.out.println("ERROR::  notifyPlayerStats(PlayerStatsInterface myStats) passed null myStats !!");
			return;
		}

		if (client.isLoggedIn()) {
			client.displayPlayerStats( myStats );
		} else {
			System.out.println("notifyPlayerStats() received while player is logged out");
		}
	}

	@Override
	public void notifyGames(List<GameListItem> games) {
		trace("notifyGames()");

		if (games == null) {
			System.out.println("ERROR::  notifyGames(List<GameListItem> games) passed null games list !!");
			return;
		}

		if (client.isLoggedIn()) {
			client.getClientFrame().getGameListPanel().setGames(games);
			
			System.out.println("Game List:");
			for (GameListItem g : games) {
				System.out.println(g.getGameID()+" p1="+g.getPlayer1Name()+" p2="+g.getPlayer2Name());
			}

		} else {
			System.out.println("notifyGames() received while player is logged out");
		}
	}

	@Override
	public void notifyGameJoined(GameInterface game) {
		trace("notifyGameJoined()");

		if (game == null) {
			System.out.println("ERROR::  notifyGameJoined(GameInterface game) passed null game !!");
			return;
		}
		
		GameWrapper wrapper = new GameWrapper(game);
		
		if (client.isLoggedIn()) {
			client.setActiveGame(wrapper);
		} else {
			System.out.println("notifyGameJoined() received while player is logged out");
		}
	}

	@Override
	public void notifyGameObserved(GameInterface game) {
		trace("notifyGameObserved()");

		if (game == null) {
			System.out.println("ERROR::  notifyGameObserved(GameInterface game) passed null game !!");
			return;
		}
		
		if (client.isLoggedIn()) {
			client.setObservedGame(game);
		} else {
			System.out.println("notifyGameObserved() received while player is logged out");
		}
			
	}
	
	@Override
	public void notifyRulesPage(RulesInterface rules) {
		trace("notifyRulesPage()");
		
		if (rules == null) {
			System.out.println("ERROR::  notifyRulesPage(RulesInterface rules) passed null rules !!");
			return;
		}
		
		if (client.isLoggedIn()) {
			displayRules( rules );
		} else {
			System.out.println("notifyRulesPage() received while player is logged out");
		}
	}

	@Override
	public void notifyFailure( ClientLogicNotify.FailureReason reason ) {
		trace("notifyFailure()");

		switch (reason) {
		case InvalidCredentials:
			Dialog.displayLoginFailedDialog();
			client.setState( ClientState.LOGGED_OUT );
			client.displayMainFrame();
			break;
		case GameNotFound:
			// TODO 
			break;
		case GameNotJoinable:
			// TODO
			break;
		case ServerLimitReached:
			// TODO
			break;
		default: break;				
		}
	}


	/**
	 * Opens the frame to display the Stratego rules.
	 * @param rules
	 */
	static public void displayRules(RulesInterface rules) {
		// FIXME - should instantiate a StrategoRules object
		JFrame rulesFrame = new JFrame();
		rulesFrame.setTitle("Stratego Rules");
	}

}
